﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

//C语言中结构体中只能定义变量，不能定义函数
//C++中结构体可以定义函数

//在c++中，class和struct都能来定义类，但是class默认私有，struct默认公有

struct ListNode_c
{
	int val;
	struct ListNode_c* next;
	struct ListNode_c* prev;
};

struct ListNode_cpp
{
	int val;
	ListNode_c* next;//可以看成一个类
	ListNode_c* prev;

	//还能定义函数
	ListNode_cpp* CreatNode(int x)
	{
	
	}
};

//类里面可以定义两个东西，1.成员变量，2.成员方法（函数）
//在类里定义的函数默认为内联函数
//函数的声明的定义分离,声明放在类内
class Person
{
	char _name[10];
	int age;

	void print()
	{

	}
};

//访问限定符（class默认限定符是private）
//public 公有
//protected 保护
//private	私有
//访问限定符的作用域为访问限定符出现的位置到下一个访问限定符出现为止
//一般情况下，成员变量都是比较隐私的，都会定义为隐私或保护
class Student
{
public:
	void ShowInfo()
	{
		cout << _name << endl;
		cout << _age << endl;
		cout << _stuid << endl;
	}


	int _GetAge()
	{
		return _age;
	}
private:
	char* _name;//这些都是变量的声明，还没有定义  0~3
	int _age;//4~7
	int _stuid;//8~11
};

//定义一个数据结构栈类
class Stack
{
public:
	void Init(int x)
	{

	}
	void Push(int x)
	{

	}
	void Pop()
	{

	}
	void Top();

protected:
	int* _a;//0~3
	size_t top;//8~15
	size_t capacity;//16~23
};

//类外定义
void Stack::Top()
{
	//..
}

//封装，将数据和方法定义在一起

class A1
{
	int a;//0~3
	char b;//4
};

//类中仅有成员函数
class A2
{
public:
	void f1()
	{

	}
};

//类中没有东西
class A3
{

};

class Data
{
private:
	int _year;
	int _month;
	int _day;
public:
	void Init(int year, int month, int day)//void Init(Data*this,int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;

		//实际上会加上this指针
		//this->_year = year;
		//this->_month = month;
		//this->_day = day;
	}
	void _print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	//编译器会将函数进行下例处理，加上隐含的this指针(谁调用函数，this指针指向谁)
	//函数内部可以访问私有成员
	//void _print(Data*this)//指向类的指针，通过指针就可以找到day，month，year
	//{
	//	cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
	//}
};


class A
{
public:
	void PrintA()
	{
		cout << _a << endl;
		//cout<<this->_a<<endl;
		//如果this是空的话会崩溃
	}

	void Show()
	{
		cout << "show()" << endl;
		//不会崩溃
	}
private:
	int _a;
};


int main()
{
	//类实例化对象,相当于定义出了类的成员变量
	//Student s1;
	//Student s2;

	//在类外面无法访问私有成员和保护成员
	//s1.age = 10;
	Stack st;
	st.Push(1);

	cout << sizeof(st) << endl;
	//类的实例化中只存储成员变量，不存储成员函数(类的实例化，就是用自己定义的类型定义对象)
	//这是为什么呢？
	//因为一个类可以实例化多个对象，每个对象都能存储不能的值，但是调用的成员函数都是同一个函数
	//如果每个对象都放成员函数，而这些成员函数都是一样的，会大量浪费空间

	//如何计算一个类实例化对象的大小，计算成员变量之和，并且考虑内存对齐规则？
	cout << sizeof(A1) << endl;

	//类中没有成员变量其大小是1
	cout << sizeof(A2) << endl;
	cout << sizeof(A3) << endl;

	Data d1;
	d1.Init(2023, 11, 24);//d1.Init(&d1,2023,11,24)
	d1._print();
	//实际上包含隐含this指针,谁调用这个成员函数，就会把这个对象传给this指针，再通过指针找到year，month，day
	//d1._print(&d1)


	//运行下列代码会发生什么情况？编译不通过，崩溃？正常运行？
	A* p = NULL;//只是把空指针传给this
	//p->PrintA();//崩溃
	p->Show();//正常运行  p->show(p)
	//成员函数存在公共代码段，所以p->show不会去p指向的对象找
	//访问成员变量，才会去找

	//A a;
	//a.PrintA //a->printA(&a)
}

//面试题
//c++中struct和class的区别是什么？
//c++兼容c语言，所以c++中可以用struct去定义结构体使用。另外，c++还可以用struct去定义类
//和class定义的类是一样的，区别是struct定义的类默认是公有的，而class定义的类默认是公有的

//函数声明和定义的区别
//声明是一种承诺，但是还没做。定义是把这件事做完了
//只声明不定义就会报错

//为什么没有成员变量的类的大小是1？而不是0？
//这里开一个字节不是为了存储数据，而是占位。表示这个类存在，好区分不同的类

//this指针存在哪里？（this指针存在地址空间哪个区域？)
//this指针存在栈中,因为他是一个形式参数，函数参数都存在栈中(linux)
//vs下是在ecx这个寄存器来传递,这是由于this指针需要经常用，寄存器的速度比较快